<script setup lang="ts" name="PanelCalledElement">
import { mapState } from 'pinia'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import * as calledElement from '../../utils/calledElement'
import EventEmitter from '@/utils/EventEmitter'

const form = ref({
  businessKey: false,
  type: '',
  expression: '',
  calledElement: '',
  caseRef: '',
  bindingType: '',
  version: '',
  versionTag: '',
  tenantId: '',
  variableMappingType: '',
  variableMappingClass: '',
  variableMappingDelegateExpression: ''
})

const mapStates = computed(() => {
  return mapState(useModelerStore, ['getActive'])
})

const calledElementTypeOptions = ref([])
const bindingTypeList = ref([])
const variableMappingTypeList = ref([])

const calledElementTypeChange = (v) => {
  bindingTypeList.value = calledElement.getBindingTypeOptions(v)
  if (v === 'bpmn') {
    variableMappingTypeList.value = calledElement.getVariableMappingTypeOptions()
  }
  calledElement.setCalledElementTypeValue(mapStates.value.getActive(), v)
}
const calledElementChange = (v) => {
  calledElement.setCalledElementValue(mapStates.value.getActive(), v)
}
const caseRefChange = (v) => {
  calledElement.setCaseRefValue(mapStates.value.getActive(), v)
}
const bindingTypeChange = (v) => {
  if (form.value.type === 'bpmn') {
    calledElement.setCalledElementBindingTypeValue(mapStates.value.getActive(), v)
  } else {
    calledElement.setCaseRefBindingTypeValue(mapStates.value.getActive(), v)
  }
}
const versionChange = (v) => {
  if (form.value.type === 'bpmn') {
    calledElement.setCalledElementVersionValue(mapStates.value.getActive(), v)
  } else {
    calledElement.setCaseRefVersionValue(mapStates.value.getActive(), v)
  }
}
const versionTagChange = (v) => {
  calledElement.setCalledElementVersionTagValue(mapStates.value.getActive(), v)
}
const tenantIdChange = (v) => {
  if (form.value.type === 'bpmn') {
    calledElement.setCalledElementTenantIdValue(mapStates.value.getActive(), v)
  } else {
    calledElement.setCaseRefTenantIdValue(mapStates.value.getActive(), v)
  }
}
const businessKeyChange = (v) => {
  calledElement.setBusinessKeyValue(mapStates.value.getActive(), v)
}
const businessKeyExpressionChange = (v) => {
  calledElement.setBusinessKeyExpression(mapStates.value.getActive(), v)
}
const variableMappingTypeChange = (v) => {
  calledElement.setDelegateVariableMappingTypeValue(mapStates.value.getActive(), v)
}
const variableMappingClassChange = (v) => {
  calledElement.setVariableMappingClassValue(mapStates.value.getActive(), v)
}
const variableMappingDelegateExpressionChange = (v) => {
  calledElement.setVariableMappingDelegateExpressionValue(mapStates.value.getActive(), v)
}

const resetForm = () => {
  form.value = {
    businessKey: false,
    type: '',
    expression: '',
    calledElement: '',
    caseRef: '',
    bindingType: '',
    version: '',
    versionTag: '',
    tenantId: '',
    variableMappingType: '',
    variableMappingClass: '',
    variableMappingDelegateExpression: ''
  }
}

const initData = () => {
  resetForm()
  calledElementTypeOptions.value = calledElement.getCalledElementTypeOptions()
  form.value.type = calledElement.getCalledElementTypeValue(mapStates.value.getActive())
  if (form.value.type) {
    bindingTypeList.value = calledElement.getBindingTypeOptions(form.value.type)
    if (form.value.type === 'bpmn') {
      variableMappingTypeList.value = calledElement.getVariableMappingTypeOptions()
      form.value.calledElement = calledElement.getCalledElementValue(mapStates.value.getActive())
      form.value.bindingType = calledElement.getCalledElementBindingTypeValue(mapStates.value.getActive())
      if (form.value.bindingType === 'version') {
        form.value.version = calledElement.getCalledElementVersionValue(mapStates.value.getActive())
      } else if (form.value.bindingType === 'versionTag') {
        form.value.versionTag = calledElement.getCalledElementVersionTagValue(mapStates.value.getActive())
      }
      form.value.tenantId = calledElement.getCalledElementTenantIdValue(mapStates.value.getActive())
      form.value.variableMappingType = calledElement.getDelegateVariableMappingTypeValue(mapStates.value.getActive())
      if (form.value.variableMappingType === 'class') {
        form.value.variableMappingClass = calledElement.getVariableMappingClassValue(mapStates.value.getActive())
      } else if (form.value.variableMappingType === 'delegateExpression') {
        form.value.variableMappingDelegateExpression = calledElement.getVariableMappingDelegateExpressionValue(mapStates.value.getActive())
      }
    } else if (form.value.type === 'cmmn') {
      form.value.caseRef = calledElement.getCaseRefValue(mapStates.value.getActive())
      form.value.bindingType = calledElement.getCaseRefBindingTypeValue(mapStates.value.getActive())
      if (form.value.bindingType === 'version') {
        form.value.version = calledElement.getCaseRefVersionValue(mapStates.value.getActive())
      }
      form.value.tenantId = calledElement.getCaseRefTenantIdValue(mapStates.value.getActive())
    }
  }
  form.value.businessKey = calledElement.getBusinessKeyValue(mapStates.value.getActive())
  if (form.value.businessKey) {
    form.value.expression = calledElement.getBusinessKeyExpression(mapStates.value.getActive())
  }
}

const eventEmitterListener = () => {
  if (calledElement.isCalledElementSupported(mapStates.value.getActive())) {
    initData()
  }
}

onBeforeUnmount(() => {
  EventEmitter.removeListener('element-update', eventEmitterListener)
})

onMounted(() => {
  initData()
  EventEmitter.on('element-update', eventEmitterListener)
})
</script>

<template>
  <el-collapse-item name="called-element">
    <template #title>
      <div class="collapse-header">
        <svg-icon icon="ri:file-cloud-fill"></svg-icon>
        <h2>调用元素</h2>
      </div>
    </template>
    <el-form-item label="类型">
      <el-select v-model="form.type" clearable @change="calledElementTypeChange">
        <el-option v-for="item in calledElementTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </el-form-item>
    <el-form-item v-if="form.type === 'bpmn'" label="调用元素">
      <el-input v-model="form.calledElement" clearable @change="calledElementChange" />
    </el-form-item>
    <el-form-item v-if="form.type === 'cmmn'" label="案例参考">
      <el-input v-model="form.caseRef" clearable @change="caseRefChange" />
    </el-form-item>
    <el-form-item v-if="form.type !== ''" label="绑定版本">
      <el-select v-model="form.bindingType" @change="bindingTypeChange">
        <el-option v-for="item in bindingTypeList" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </el-form-item>
    <el-form-item v-if="form.type !== '' && form.bindingType === 'version'" label="版本">
      <el-input v-model="form.version" clearable @change="versionChange" />
    </el-form-item>
    <el-form-item v-if="form.type !== '' && form.bindingType === 'versionTag'" label="版本标签">
      <el-input v-model="form.versionTag" clearable @change="versionTagChange" />
    </el-form-item>
    <el-form-item v-if="form.type !== ''" label="租户ID">
      <el-input v-model="form.tenantId" clearable @change="tenantIdChange" />
    </el-form-item>
    <el-form-item label="业务标识">
      <el-switch v-model="form.businessKey" @change="businessKeyChange" />
    </el-form-item>
    <el-form-item v-if="form.businessKey" label="表达式">
      <el-input v-model="form.expression" clearable @change="businessKeyExpressionChange" />
    </el-form-item>
    <el-form-item v-if="form.type === 'bpmn'" label="代理变量映射">
      <el-select v-model="form.variableMappingType" clearable @change="variableMappingTypeChange">
        <el-option v-for="item in variableMappingTypeList" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
    </el-form-item>
    <el-form-item v-if="form.type === 'bpmn' && form.variableMappingType === 'class'" label="类名">
      <el-input v-model="form.variableMappingClass" clearable @change="variableMappingClassChange" />
    </el-form-item>
    <el-form-item v-if="form.type === 'bpmn' && form.variableMappingType === 'delegateExpression'" label="表达式">
      <el-input v-model="form.variableMappingDelegateExpression" clearable @change="variableMappingDelegateExpressionChange" />
    </el-form-item>
  </el-collapse-item>
</template>

<style scoped lang="scss">
.el-collapse-item {
  :deep(.el-collapse-item__header) {

    .collapse-header {
      display: flex;
      flex: 1;
      align-items: center;
      padding: 0 12px;

      .el-icon {
        margin-right: 6px;
        font-size: 20px !important;
      }

      h2 {
        font-weight: bold;
        font-size: 14px;
      }
    }

    .el-icon {
      font-size: 18px;
    }
  }

  :deep(.el-collapse-item__content) {
    padding-right: 12px;
    padding-bottom: 12px;
    padding-left: 12px;
  }
}
</style>
